using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace ZhenG.Tools.AnimSplitter
{
    public class AnimationSplitterWindow : EditorWindow
    {
        [MenuItem("Tools/My Tools/动画拆分器")]
        private static void OpenAnimSplitterWindow()
        {
            // 打开动画片段拆分器窗口
            AnimationSplitterWindow window = GetWindow<AnimationSplitterWindow>("动画片段拆分器");
            window.Show();
        }

        private SerializedObject _serializedObject; // 用于序列化窗口数据
        private SerializedProperty _targetProperty; // 目标游戏对象属性

        public List<GameObject> targetGameObjects = new List<GameObject>(); // 目标游戏对象列表
        public AnimationClipDataTable animationClipInformationTable; // 动画信息表

        private void OnEnable()
        {
            // 初始化序列化对象和目标属性
            _serializedObject = new SerializedObject(this);
            _targetProperty = _serializedObject.FindProperty(nameof(targetGameObjects));
        }

        private void OnGUI()
        {
            _serializedObject.Update(); // 更新序列化对象

            // 绘制信息表的对象字段
            animationClipInformationTable =
                (AnimationClipDataTable)EditorGUILayout.ObjectField("信息表", animationClipInformationTable, typeof(AnimationClipDataTable), true);

            // 绘制目标游戏对象数组
            EditorGUILayout.PropertyField(_targetProperty, new GUIContent("模型资源列表"), true);

            // 拆分动画片段按钮
            if (GUILayout.Button("拆分动画片段"))
            {
                // 检查信息表是否为空
                if (animationClipInformationTable == null)
                {
                    Debug.LogWarning("信息表为空，请指定有效的信息表！");
                    return;
                }

                // 遍历每个目标游戏对象
                foreach (GameObject gameObject in targetGameObjects)
                {
                    string assetPath = AssetDatabase.GetAssetPath(gameObject); // 获取资产路径
                    ModelImporter modelImporter = UnityEditor.AssetImporter.GetAtPath(assetPath) as ModelImporter; // 获取模型导入器
                    ProcessAnimationClips(modelImporter); // 处理动画片段
                }
            }

            _serializedObject.ApplyModifiedProperties(); // 应用修改的属性
        }

        /// <summary>
        /// 处理给定的模型导入器中的动画片段。
        /// </summary>
        /// <param name="modelImporter">需要处理的模型导入器。</param>
        private void ProcessAnimationClips(ModelImporter modelImporter)
        {
            // 检查模型导入器是否为空
            if (modelImporter == null)
                return;

            // 获取当前模型的所有动画片段
            List<ModelImporterClipAnimation> animationClips = modelImporter.clipAnimations.ToList();

            // 根据现有的动画片段数量决定创建新片段或更新现有片段
            if (animationClips.Count == 0)
            {
                CreateAnimationClips(animationClips); // 创建新的动画片段
            }
            else
            {
                UpdateAnimationClips(animationClips); // 更新已有的动画片段
            }

            // 更新模型导入器中的动画片段并保存更改
            modelImporter.clipAnimations = animationClips.ToArray();
            modelImporter.SaveAndReimport();
        }

        /// <summary>
        /// 创建新的动画片段，根据动画信息表中的数据进行添加。
        /// </summary>
        /// <param name="animationClips">当前的动画片段列表。</param>
        private void CreateAnimationClips(List<ModelImporterClipAnimation> animationClips)
        {
            // 遍历 ClipInformationForm 中的所有动画信息，添加到动画片段列表
            foreach (var clipInfo in animationClipInformationTable.clipInfos)
            {
                animationClips.Add(new ModelImporterClipAnimation()
                {
                    name = clipInfo.name, // 设置动画片段名称
                    firstFrame = clipInfo.startFrame, // 设置起始帧
                    lastFrame = clipInfo.endFrame, // 设置结束帧
                    loop = clipInfo.loop,
                });
            }
        }

        /// <summary>
        /// 更新已有的动画片段，移除无效的片段并添加或更新动画。
        /// </summary>
        /// <param name="animationClips">当前的动画片段列表。</param>
        private void UpdateAnimationClips(List<ModelImporterClipAnimation> animationClips)
        {
            // 创建一个集合，包含要保留的动画名称
            HashSet<string> validClipNames =
                new HashSet<string>(animationClipInformationTable.clipInfos.Select(info => info.name));

            RemoveInvalidAnimationClips(animationClips, validClipNames); // 移除无效的动画片段
            AddOrUpdateAnimationClips(animationClips); // 更新或添加动画片段
        }

        /// <summary>
        /// 移除无效的动画片段，即不在有效动画名称集合中的动画。
        /// </summary>
        /// <param name="animationClips">当前的动画片段列表。</param>
        /// <param name="validClipNames">有效动画名称的集合。</param>
        private void RemoveInvalidAnimationClips(List<ModelImporterClipAnimation> animationClips,
            HashSet<string> validClipNames)
        {
            // 移除所有不在有效动画名称集合中的动画片段
            animationClips.RemoveAll(clip => !validClipNames.Contains(clip.name));
        }

        /// <summary>
        /// 添加或更新动画片段，如果存在同名动画则更新其帧信息，否则添加新的动画片段。
        /// </summary>
        /// <param name="animationClips">当前的动画片段列表。</param>
        private void AddOrUpdateAnimationClips(List<ModelImporterClipAnimation> animationClips)
        {
            // 遍历信息表中的每个动画信息
            foreach (var clipInfo in animationClipInformationTable.clipInfos)
            {
                // 查找是否存在同名的动画片段
                var existingClip = animationClips.FirstOrDefault(clip => clip.name.Equals(clipInfo.name));

                if (existingClip != null)
                {
                    // 更新已存在动画片段的帧信息
                    existingClip.firstFrame = clipInfo.startFrame;
                    existingClip.lastFrame = clipInfo.endFrame;
                    existingClip.loop = clipInfo.loop;
                }
                else
                {
                    // 添加新的动画片段
                    animationClips.Add(new ModelImporterClipAnimation()
                    {
                        name = clipInfo.name,
                        firstFrame = clipInfo.startFrame,
                        lastFrame = clipInfo.endFrame,
                        loop = clipInfo.loop
                    });
                }
            }
        }
    }
}